package com.sun.springbootfiledownload.service;

import com.aliyun.oss.ServiceException;
import com.sun.springbootfiledownload.dto.UploadTask;
import com.sun.springbootfiledownload.enums.UploadTaskStatus;
import com.sun.springbootfiledownload.utils.AliyunOssPlusUtil;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.Instant;
import java.util.UUID;
import java.util.concurrent.*;

@Slf4j
@Service
public class OssUploadQueueService {
    // 任务队列（最大1000个待处理任务）
    private final BlockingQueue<UploadTask> taskQueue = new LinkedBlockingQueue<>(1000);

    // 任务存储（生产环境建议用Redis）
    private final ConcurrentMap<String, UploadTask> taskStore = new ConcurrentHashMap<>();

    @Autowired
    private AliyunOssPlusUtil ossUtil;

    @Autowired
    private Executor asyncExecutor;

    /**
     * 提交上传任务到队列
     */
    public UploadTask submitUploadTask(MultipartFile file, String folder) throws IOException {
        UploadTask task = new UploadTask(
                "task-" + UUID.randomUUID().toString().substring(0, 8),
                file.getOriginalFilename(),
                file.getSize(),
                folder,
                UploadTaskStatus.PENDING,
                0,
                null,
                null,
                Instant.now(),
                file.getBytes()
        );

        if (taskQueue.offer(task)) {
            task.setStatus(UploadTaskStatus.QUEUED);
            taskStore.put(task.getTaskId(), task);
            log.info("任务入队成功: {}", task.getTaskId());
            return task;
        } else {
            throw new ServiceException("上传队列已满，请稍后重试");
        }
    }

    /**
     * 启动队列处理器（系统启动时调用）
     */
    @PostConstruct
    public void startQueueProcessor() {
        // 使用自定义线程池处理上传任务
        asyncExecutor.execute(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    UploadTask task = taskQueue.take();
                    processUploadTask(task);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
    }

    /**
     * 处理单个上传任务
     */
    private void processUploadTask(UploadTask task) {
        task.setStatus(UploadTaskStatus.PROCESSING);
        updateTaskProgress(task, 0);

        try {
            // 使用OSS工具类进行上传（根据文件大小自动选择普通/分片上传）
            String ossUrl;
//            if (task.getFileSize() > 20 * 1024 * 1024) { // 大于20MB使用分片上传
//                File tempFile = createTempFile(task);
//                try {
//                    ossUrl = ossUtil.uploadLargeFile(tempFile, task.getTargetFolder());
//                } finally {
//                    Files.deleteIfExists(tempFile.toPath());
//                }
//            } else {
//                // 小文件直接上传
//                byte[] fileBytes = getFileBytes(task);
//                ossUrl = ossUtil.safeUpload(fileBytes, task.getFileName(), task.getTargetFolder());
//            }
            byte[] fileBytes = getFileBytes(task);
            ossUrl = ossUtil.safeUpload(fileBytes, task.getFileName(), task.getTargetFolder());

            task.setOssUrl(ossUrl);
            task.setStatus(UploadTaskStatus.COMPLETED);
            updateTaskProgress(task, 100);

        } catch (Exception e) {
            task.setStatus(UploadTaskStatus.FAILED);
            task.setErrorMsg(e.getMessage());
            log.error("任务处理失败: {}", task.getTaskId(), e);
        }
    }

    // 辅助方法：获取文件内容（模拟实现）
    private byte[] getFileBytes(UploadTask task) throws IOException {
        // 实际应从持久化存储获取
        return task.getFileBytes();
    }

    // 辅助方法：创建临时文件（模拟实现）
    private File createTempFile(UploadTask task) throws IOException {
        // 实际应写入真实文件内容
        return File.createTempFile("oss-upload-", ".tmp");
    }

    private void updateTaskProgress(UploadTask task, int progress) {
        task.setProgress(progress);
        taskStore.put(task.getTaskId(), task);
    }

    /**
     * 查询任务状态
     */
    public UploadTask getTaskStatus(String taskId) {
        return taskStore.get(taskId);
    }

    /**
     * 取消任务
     */
    public boolean cancelTask(String taskId) {
        UploadTask task = taskStore.get(taskId);
        if (task != null && task.getStatus().ordinal() < UploadTaskStatus.PROCESSING.ordinal()) {
            task.setStatus(UploadTaskStatus.CANCELLED);
            return true;
        }
        return false;
    }
}